package api

import (
	"fmt"
	"service/app/control"
	"service/app/dto"
	"service/common"
	"service/global"
	"service/utils"

	"github.com/gin-gonic/gin"
)

var (
	USER_INSERT_ERROR    = 100011
	USER_NOTEXIST        = 100012
	USER_UPDATA_FAIL     = 100013
	USER_GETPAGINAT_FAIL = 100014
	USER_DEL_ERR         = 100015
	INVALID_USER         = 100016
	USER_GET_INFO        = 100017
)

// 0.默认结构体
type UserApi struct {
	BaseApi
	Contr *control.UserContr
}

// 2.返回userApi结构体的初始化,包含挂载的函数
func CreateUser() UserApi {
	return UserApi{
		BaseApi: *BaseApi{}.BaseApiInit(),
		Contr:   control.NewUserContr(),
	}
}

// 1.将泛型挂载到 userApi上面
// @Tags user,system
// @Summary 登录接口
// @Description 登录接口测试
// @Param data body dto.LoginDto true "用户账号,用户密码"
// @Router /api/v1/pub/login [post]
// @Success 200 {object} dto.IresToken "token"
func (m UserApi) Login(ctx *gin.Context) {
	var Iuser dto.LoginDto
	if err := m.BaseReqHandle(&IBaseApiParams{Ctx: ctx, Dto: &Iuser}).GetBaseErr(); err != nil {
		m.Fail(ResponseJson{Msg: err.Error()})
		return
	}
	// 选检查密码加hash后
	res, err := m.Contr.Login(Iuser.User, ctx.ClientIP())
	if err != nil {
		m.Fail(ResponseJson{Msg: "用户名或者密码错误。!", Code: INVALID_USER})
		return
	}
	err = utils.DeCrypto(res.Password, Iuser.Password)
	if err != nil {
		m.Fail(ResponseJson{Msg: "用户名或者密码错误。", Code: INVALID_USER})
		return
	}
	// 签token
	// 调用redis储存Token
	// redis
	accessToken, _ := utils.GenerateJwt(int(res.ID), res.User, "jwt.ac_expire")
	if err := common.RdSet(fmt.Sprintf("accessToken_%s", Iuser.User), accessToken, "jwt.ac_expire"); err != nil {
		global.Logger.Errorf(fmt.Sprintf("redis存入数据出错accessToken,%s", accessToken))
	}
	refreshToken, _ := utils.GenerateJwt(int(res.ID), res.User, "jwt.rf_expire")
	if err := common.RdSet(fmt.Sprintf("refreshToken_%s", Iuser.User), refreshToken, "jwt.rf_expire"); err != nil {
		global.Logger.Errorf(fmt.Sprintf("redis存入数据出错refreshToken,%s", refreshToken))
	}
	m.Okay(ResponseJson{Msg: fmt.Sprintf("%s 欢迎回来", Iuser.User), Data: dto.IresToken{AccessToken: accessToken, RefreshToken: refreshToken}})

}

// @Tags user,system
// @Summary 创建用户 regist
// @Description 创建用户
// @Router /api/v1/user/regist [post]
// @Param object body dto.AdduserDto true "用户资料"
func (m UserApi) Adduser(ctx *gin.Context) {
	var Iuser dto.AdduserDto
	// 数据校验dto
	if err := m.BaseReqHandle(&IBaseApiParams{Ctx: ctx, Dto: &Iuser}).GetBaseErr(); err != nil {
		return
	}
	// 从校验赋值会传过来的值写入数据库
	Iuser.Register_Ip = ctx.ClientIP()
	if err := m.Contr.AddUser(&Iuser); err != nil {
		m.ServerFail(ResponseJson{
			Code: USER_INSERT_ERROR,
			Msg:  err.Error()})
		return
	}
	m.Okay(ResponseJson{Data: &Iuser})
}

// @Tags user
// @Summary 获取用户by id
// @Description 获取用户by id
// @Router /api/v1/user/id/{id} [get]
// @Param object query dto.ReqUriIdDto true "用户资料"
// @Security ApiKeyAuth
func (m UserApi) GetUserById(ctx *gin.Context) {
	var IuserId dto.ReqUriIdDto
	if err := m.BaseReqHandle(&IBaseApiParams{Ctx: ctx, Dto: &IuserId, ReqUri: true}).GetBaseErr(); err != nil {
		return
	}
	user, err := m.Contr.GetUserById(IuserId)
	if err != nil {
		m.ServerFail(ResponseJson{
			Code: USER_NOTEXIST,
			Msg:  err.Error()})
		return
	}
	m.Okay(ResponseJson{Data: user})
}

// @Tags user
// @Summary 用户列表,分页
// @Description 需要传ReqPaginat
// @Router /api/v1/user/list [GET]
// @Param object query dto.ReqPaginat true "分页"
// @Security ApiKeyAuth
func (m UserApi) PaginatUser(ctx *gin.Context) {
	var PaginatVali dto.ReqPaginatUser
	if err := m.BaseReqHandle(&IBaseApiParams{Ctx: ctx, Dto: &PaginatVali, ReqQey: true}).GetBaseErr(); err != nil {
		m.Fail(ResponseJson{Msg: err.Error()})
		return
	}
	PaginatUser := dto.ReqPaginat{Page: PaginatVali.Page, Limit: PaginatVali.Limit, Keyword: PaginatVali.Keyword, Order: PaginatVali.Order, Key: PaginatVali.Key, OrderKey: PaginatVali.OrderKey}
	UserList, total, err := m.Contr.GetUserList(&PaginatUser)
	if err != nil {
		m.ServerFail(ResponseJson{
			Code: USER_GETPAGINAT_FAIL,
			Msg:  err.Error()})
		return
	}
	m.Okay(ResponseJson{Data: UserList, Total: total})
}

// @Tags user
// @Summary 用户更新用户
// @Description 用户更新用户
// @Router /api/v1/user/id/{id} [PUT]
// @Param object query dto.ReqUriIdDto true "用户ID"
// @Param object body dto.UpdataUserDto true "用户资料updata"
// @Security ApiKeyAuth
func (m UserApi) UpdataUser(ctx *gin.Context) {
	var UserParam dto.UpdataUserDto
	if err := m.BaseReqHandle(&IBaseApiParams{Ctx: ctx, Dto: &UserParam, AllParams: true}).GetBaseErr(); err != nil {
		return
	}
	err := m.Contr.UpdataUser(UserParam)
	if err != nil {
		m.ServerFail(ResponseJson{
			Code: USER_UPDATA_FAIL,
			Msg:  err.Error()})
		return
	}
	ctx.JSON(200, gin.H{"message": "okay"})
}

// @Tags user
// @Summary 用户删除
// @Description 用户删除
// @Router /api/v1/user/id/{id} [DELETE]
// @Param object query dto.ReqUriIdDto true "用户ID"
// @Security ApiKeyAuth
func (m UserApi) DelUser(c *gin.Context) {
	var userId dto.ReqUriIdDto
	if err := m.BaseReqHandle(&IBaseApiParams{Ctx: c, ReqUri: true, Dto: &userId}).GetBaseErr(); err != nil {
		return
	}
	if err := m.Contr.DelUser(userId); err != nil {
		m.ServerFail(ResponseJson{
			Code: USER_DEL_ERR,
			Msg:  err.Error()})
		return
	}
	c.JSON(200, gin.H{"message": "删除用户成功!"})
}

// @Summary 获取用户资料,这里是从authmid中返回
// @Description 获取用户资料 @Success <状态码> <返回类型> <返回描述>
// @Tags user
// @Router /api/v1/user/info [GET]
// @Success 200 {object} ResponseJson "每次刷新的用户资料"
// @Security ApiKeyAuth
func (m UserApi) InfoUser(c *gin.Context) {
	m.Ctx = c
	profile := m.GetCtxUser()
	// 缺返回前端menulist接口
	info, err := m.Contr.InfoUserC(profile)
	if err != nil {
		m.Fail(ResponseJson{Msg: "获取用户信息失败!", Code: USER_GET_INFO})
		return
	}
	m.Okay(ResponseJson{Data: info})
}

// @Tags user
// @Summary 返回完整的用户表 role-perm
// @Description 2024年12月10日12:05:47
// @Router /api/v1/user/perm/{id} [GET]
// @Param object query dto.ReqUriIdDto true "用户ID"
// @Security ApiKeyAuth
func (m UserApi) User_role_Perm(c *gin.Context) {
	var userId dto.ReqUriIdDto
	if err := m.BaseReqHandle(&IBaseApiParams{Ctx: c, ReqUri: true, Dto: &userId}).GetBaseErr(); err != nil {
		return
	}
	userAllInfo, err := m.Contr.UserPermC(userId.Id)
	if err != nil {
		m.Fail(ResponseJson{Msg: "获取用户信息失败!"})
		return
	}
	m.Okay(ResponseJson{Data: userAllInfo})
}
